#include <iterator>
#include "MarkupSTL.h"
#include "global.h"
#include "cmd.h"
#include "Game.h"
#include "RedisClient.h"
#include "Logic.h"
#include "json.h"
#include "Host.h"
#include "NodeServer.h"
#include <limits>
#include "1700_login.pb.h"
#include "800_online.pb.h"
#include "1600_agent.pb.h"
#include "4700_roomalloc.pb.h"
#include "1300_user_info.pb.h"
// #include "1700_account.pb.h"

CGameServer::CGameServer():m_timerflag(false)
{
}

CGameServer::~CGameServer()
{
}

bool CGameServer::InitGame()
{
	return true;
}

int CGameServer::OnBYTimeOut(int Timerid)
{
	switch (Timerid)
	{
	case TIMERID_HEART_BEAT_SYN:
	{
		procHeartBeatSyn();
		break;
	}
	default:
		break;
	}
	return 0;
}

int CGameServer::ProcessPacket(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	log_debug("msg from type,%hu,id,%u,pack head,srctype,%hu,srcid,%u,dsttype,%hu,dstid,%u cmd%u", pHandler->getType(), pHandler->getId(), inputPkg->GetSrcType(), inputPkg->GetSrcSvid(), inputPkg->GetDstType(), inputPkg->GetDstSvid(), inputPkg->GetCmdType());
	if (CONN_TYPE_ACCEPT == pHandler->getConnType() && SERVER_TYPE_GAME_PLAYER == inputPkg->GetSrcType())
		ProcPlayerPack(pHandler, inputPkg);
	else if (CONN_TYPE_CONN == pHandler->getConnType())
		ProcSrvPack(pHandler, inputPkg);
	else
		log_error("invalid pack,conn typd,%d,src type,%d", pHandler->getConnType(), inputPkg->GetSrcType());

	return 0;
}

int CGameServer::ProcPlayerPack(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	resetSynCount(pHandler);

	unsigned int cmd = inputPkg->GetCmdType();
	if (AGENT_HEART_BEAT == cmd || agent::AGENT_CMD_HEART_BEAT == cmd)
	{
		ProcHeartBeat(pHandler, inputPkg);
		return 0;
	}
	unsigned int dstSrvType = inputPkg->GetDstType();
	if(SERVER_TYPE_ACCOUNT == dstSrvType)
	{
		return ProcPlayerAccount(pHandler, inputPkg);
	}
	else if (SERVER_TYPE_ROOMALLOC == dstSrvType)
	{
		return ProcPlayerRoomAlloc(pHandler, inputPkg);
	}

	if (pHandler->getId() > 0)//�ѵ�¼�ɹ�
	{
		sendToSrv(pHandler, inputPkg);
	}
	else
	{
		log_error("no login,cmd,%d", inputPkg->GetCmdType());
	}
	return 0;
}

int CGameServer::ProcSrvPack(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	unsigned int cmd = inputPkg->GetCmdType();
	unsigned short stype = pHandler->getType();
	switch (stype)
	{
	case SERVER_TYPE_ACCOUNT://�˺ŷ�����ʱ���ͻ��˿��ܻ�û��uin
	{
		if (account_proto::ACCOUNT_CMD_VERIFY_LOGIN_TOKEN_RESP == cmd)
		{
			return ProcLoginRsp(pHandler, inputPkg);
		}
		break;
	}
	case SERVER_TYPE_ONLINE:
	{
		return ProcOnlineSrvPack(pHandler, inputPkg);
		break;
	}
	case SERVER_TYPE_ROOMALLOC:
	{
		if (agent::AGENT_CMD_ROOMALLOC_REG_NOTIFY == cmd)
		{
			return ProcRoomAllocReg(pHandler, inputPkg);
		}
		break;
	}
	case SERVER_TYPE_USERINFO:
	{
		if (client_proto::UISMI_FORBIT_USER_PUSH == cmd)
		{
			return ProcUserBanPush(pHandler, inputPkg);
		}
		break;
	}
	default:
		break;
	}
	
	sendToPlayer(pHandler, inputPkg);
	return 0;
}

int CGameServer::ProcPlayerAccount(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	unsigned int cmd = inputPkg->GetCmdType();
	if (account_proto::ACCOUNT_CMD_VERIFY_LOGIN_TOKEN_REQ == cmd)
	{
		CClientHandler* handler = static_cast<CClientHandler*>(pHandler);
		unsigned int tmpuin = handler->m_HandlerID;
		inputPkg->SetSrcSvid(tmpuin);
		stPlayerHandler stplayer;
		stplayer.m_phandler = handler;
		m_unloginPlayer.insert(make_pair(tmpuin, stplayer));
		//m_unloginPlayer[tmpuin].m_phandler = handler;
		srvtypeRandSend(SERVER_TYPE_ACCOUNT, inputPkg);

		log_debug("tmpuin,%d, flowid,%d", tmpuin, handler->m_HandlerID);
	}
	else
	{
		unsigned int uid = inputPkg->GetSrcSvid();
		if (0 == uid)
		{
			log_error("wrong param,cmd:%d,uid,%d", cmd, uid);
		}
		srvtypeModSend(SERVER_TYPE_ACCOUNT, uid, inputPkg);
	}
		
    return 0;
}


int CGameServer::ProcPlayerRoomAlloc(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	unsigned int cmd = inputPkg->GetCmdType();
	int32_t game_id = 0;
	if (roomalloc::ROOMALLOC_CMD_ALLOC_TABLE_REQ == cmd || roomalloc::ROOMALLOC_CMD_LEVEL_CONFIG_REQ == cmd || roomalloc::ROOMALLOC_CMD_LEVEL_TABLE_INFO_REQ == cmd)
	{
		NETOutputPacket pack;
		pack.Copy(inputPkg->packet_buf(), inputPkg->packet_size());
		if (roomalloc::ROOMALLOC_CMD_ALLOC_TABLE_REQ == cmd)
		{
			roomalloc::AllocTableReq msg;
			if (!inputPkg->parsePb(&msg))
			{
				log_error("parse room alloc req fail,uid,%u,uid,%u", pHandler->getId(), inputPkg->GetSrcSvid());
				return -1;
			}
			game_id = msg.game_id();
		}
		else if (roomalloc::ROOMALLOC_CMD_LEVEL_CONFIG_REQ == cmd)
		{
			roomalloc::GameLevelConfigReq msg;
			if (!inputPkg->parsePb(&msg))
			{
				log_error("parse room level config req fail,uid,%u,uid,%u", pHandler->getId(), inputPkg->GetSrcSvid());
				return -1;
			}
			game_id = msg.game_id();
		}
		else if (roomalloc::ROOMALLOC_CMD_LEVEL_TABLE_INFO_REQ == cmd)
		{
			roomalloc::LevelTableInfoReq msg;
			if (!inputPkg->parsePb(&msg))
			{
				log_error("parse room LevelTableInfoReq fail,uid,%u,uid,%u", pHandler->getId(), inputPkg->GetSrcSvid());
				return -1;
			}
			game_id = msg.game_id();
		}

		map<unsigned int, set<unsigned int> >::const_iterator itor = m_roomAlloc.find(game_id);
		if (m_roomAlloc.end() != itor)
		{
			if (itor->second.size() > 0)
			{
				unsigned int dstsid = 0;
				set<unsigned int>::const_iterator itor1 = itor->second.begin();
				if(itor->second.size() > 1)
				{
					static unsigned int s_randallocindex = 0;
					s_randallocindex = ++s_randallocindex % numeric_limits<unsigned int>::max();
					unsigned int index = s_randallocindex % itor->second.size();
					::advance(itor1, index);
					dstsid = *itor1;
				}
				dstsid = *itor1;
				
				m_pHost->SendPacket(&pack, SERVER_TYPE_ROOMALLOC, dstsid);
				log_info("room alloc req send,uid,%u,dstsvid,%u", inputPkg->GetSrcSvid(), dstsid);

				return 0;
			}
		}
		if (roomalloc::ROOMALLOC_CMD_ALLOC_TABLE_REQ == cmd)
		{
			roomalloc::AllocTableResp rsp;
			rsp.set_result(1);
			m_pHost->SendPlayerPb(pHandler, roomalloc::ROOMALLOC_CMD_ALLOC_TABLE_RESP, inputPkg->GetSrcSvid(), &rsp);
		}
		log_error("no room alloc srv,uid,%u,gameid,%d", inputPkg->GetSrcSvid(), game_id);
	}
	else
	{
		srvtypeRandSend(SERVER_TYPE_ROOMALLOC, inputPkg);
		log_debug("other room alloc msg,%u", cmd);
	}

	return 0;
}

int CGameServer::ProcRoomAllocReg(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	agent::RoomAllocRegNotify msg;
	if (!inputPkg->parsePb(&msg))
	{
		log_error("parse room alloc reg fail,srvid,%u", pHandler->getId());
		return -1;
	}

	if (!(msg.gameid() > 0))
	{
		log_error("room alloc reg,wrong param,gameid,%u", msg.gameid());
		return -1;
	}

	unsigned int sid = pHandler->getId();
	unsigned int gameid = msg.gameid();

	map<unsigned int, unsigned int>::const_iterator itor = m_sidGameid.find(sid);
	if (m_sidGameid.end() != itor)
	{
		map<unsigned int, set<unsigned int> >::iterator itor1 = m_roomAlloc.find(itor->second);
		if (m_roomAlloc.end() != itor1)
		{
			itor1->second.erase(sid);
		}

		m_sidGameid.erase(itor);
	}

	m_roomAlloc[gameid].insert(sid);
	m_sidGameid.insert(std::make_pair(sid, gameid));
	log_debug("room alloc reg,svid,%u,gameid,%u", sid, gameid);

	return 0;
}

int CGameServer::ProcLoginRsp(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	NETInputPacket pack;
	pack.Copy(inputPkg->packet_buf(), inputPkg->packet_size());

	account_proto::VerifyLoginTokenResp msg;
	inputPkg->parsePb(&msg);
	unsigned int uid = msg.uid();
	unsigned int tmpuin = msg.temp_uin();
	int ret = msg.result();

	map<unsigned int, stPlayerHandler>::iterator itor = m_unloginPlayer.find(tmpuin);
	CClientHandler* handler = NULL;
	if (m_unloginPlayer.end() != itor && itor->second.m_phandler)
	{
		handler = itor->second.m_phandler;
	}
	if (0 == ret && uid > 0 && tmpuin > 0)
	{
		if (m_unloginPlayer.end() != itor && itor->second.m_phandler)
		{
			//tow user(diff uid) use the same tcp conn 
			if (SERVER_TYPE_GAME_PLAYER == itor->second.m_phandler->getType() && itor->second.m_phandler->getId() > 0 && uid != itor->second.m_phandler->getId())
			{
				log_alert("user %u and user %u user the same tcp conn,flowid,%u", uid, itor->second.m_phandler->getId(), itor->second.m_phandler->m_HandlerID);
				map<unsigned int, stPlayerHandler>::iterator itor2 = m_loginPlayer.find(itor->second.m_phandler->getId());
				if (m_loginPlayer.end() != itor2)
				{
					m_loginPlayer.erase(itor2);
					synToOnlineOff(itor->second.m_phandler->getId());
					log_alert("user %u and user %u user the same tcp conn,rm user %u", uid, itor->second.m_phandler->getId(), itor->second.m_phandler->getId());
				}
			}

			itor->second.m_phandler->setType(SERVER_TYPE_GAME_PLAYER);
			itor->second.m_phandler->setId(uid);

			map<unsigned int, stPlayerHandler>::iterator itor1 = m_loginPlayer.find(uid);
			if (m_loginPlayer.end() != itor1)
			{
				if (itor1->second.m_phandler && handler->m_HandlerID != itor1->second.m_phandler->m_HandlerID)//more than one login req may be one socket connection
				{
					kick(uid, 1, true);
				}
// 				else
// 				{
// 					m_loginPlayer.erase(itor1);
// 				}
			}

			m_loginPlayer.insert(make_pair(uid, itor->second));
			m_unloginPlayer.erase(itor);

			synToOnlineOn(uid);
			log_debug("tmpuin,%d, flowid,%d, uid,%d", tmpuin, handler->m_HandlerID, uid);
		}
	}
	else
	{
		log_error("wrong param,uid,%d,tmpuin,%d, ret,%d", uid, tmpuin, ret);
	}

	if (handler)
	{
		handler->Send(&pack);
	}


	return 0;
}

int CGameServer::ProcUserBanPush(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	NETInputPacket pack;
	pack.Copy(inputPkg->packet_buf(), inputPkg->packet_size());
	sendToPlayer(pHandler, &pack);

	client_proto::ForbitUserPush msg;
	if (!inputPkg->parsePb(&msg))
	{
		log_error("parse user ban push fail,srvid,%u", pHandler->getId());
		return -1;
	}
	if (!(msg.user_id() > 0))
	{
		log_error(" user ban push wrong uid,%u", msg.user_id());
		return -1;
	}
	kick(msg.user_id(), 3, true);
	log_alert("ban user,%u,from,%u", msg.user_id(), pHandler->getId());

	return 0;
}

int CGameServer::ProcOnlineSrvPack(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	unsigned int cmd = inputPkg->GetCmdType();
	switch (cmd)
	{
	case ONLINE_KICK:
	{
		ProcKick(pHandler, inputPkg);
		break;
	}
	default:
		break;
	}
	return 0;
}

int CGameServer::ProcKick(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	unsigned int uid = inputPkg->ReadInt();
	unsigned int reason = inputPkg->ReadInt();
	kick(uid, reason);

	return 0;
}

int CGameServer::sendToSrv(SocketHandler* pHandler, NETInputPacket* pack)
{
	unsigned short dsttype = pack->GetDstType();
	unsigned int dstsid = pack->GetDstSvid();
	if (dsttype > 0 && dstsid > 0)
	{
		sendToOneSrv(dsttype, dstsid, pack);
	}
	else if (dsttype > 0)
	{
		unsigned int uid = pack->GetSrcSvid();
		if (uid > 0)
			srvtypeModSend(dsttype, uid, pack);
		else
		{
			srvtypeRandSend(dsttype, pack);
		}
	}


	return 0;
}

int CGameServer::sendToOneSrv(unsigned short stype, unsigned int sid, NETInputPacket* pack)
{

	m_pHost->SendPacket(pack, stype, sid);
// 	map<unsigned short, map<unsigned int, CClient*> >::iterator itor = m_node.find(stype);
// 	if (m_node.end() != itor)
// 	{
// 		map<unsigned int, CClient*>::iterator itor1 = itor->second.find(sid);
// 		if (itor->second.end() != itor1)
// 		{
// 			itor1->second->Send(pack);
// 		}
// 	}
	return 0;
}

int CGameServer::srvtypeModSend(unsigned short stype, unsigned int mod, CCPacketBase* pack)
{
	m_pHost->SendtoSrv(pack, stype, mod);
// 	map<unsigned short, map<unsigned int, CClient*> >::iterator itor = m_node.find(stype);
// 	map<unsigned short, vector<unsigned int> >::iterator vitor = m_nodeId.find(stype);
// 	if (m_node.end() != itor && m_nodeId.end() != vitor && vitor->second.size() > 0)
// 	{
// 		assert(itor->second.size() == vitor->second.size());
// 		int index = mod % vitor->second.size();
// 		unsigned int sid = vitor->second[index];
// 		map<unsigned int, CClient*>::iterator itor1 = itor->second.find(sid);
// 		if (itor->second.end() != itor1)
// 		{
// 			itor1->second->Send(pack);
// 		}
// 		else
// 		{
// 			log_debug("find no srv %d", sid);
// 		}
// 	}
// 	else
// 	{
// 		log_debug("find no srv type %d", stype);
// 	}
	return 0;
}

int CGameServer::srvtypeRandSend(unsigned short stype, NETInputPacket* pack)
{
	static unsigned int randindex = 0;
	randindex = ++randindex % numeric_limits<unsigned int>::max();

	m_pHost->SendtoSrv(pack, stype, randindex);
// 	map<unsigned short, map<unsigned int, CClient*> >::iterator itor = m_node.find(stype);
// 	map<unsigned short, vector<unsigned int> >::iterator vitor = m_nodeId.find(stype);
// 	if (m_node.end() != itor && m_nodeId.end() != vitor && vitor->second.size() > 0)
// 	{
// 		assert(itor->second.size() == vitor->second.size());
// 		randindex = ++randindex % numeric_limits<unsigned int>::max();
// 		int index = randindex % vitor->second.size();
// 		unsigned int sid = vitor->second[index];
// 		map<unsigned int, CClient*>::iterator itor1 = itor->second.find(sid);
// 		if (itor->second.end() != itor1)
// 		{
// 			itor1->second->Send(pack);
// 			log_debug("srv %d, type %d", sid, stype);
// 		}
// 		else
// 		{
// 			log_debug("find no srv %d", sid);
// 		}
// 	}
// 	else
// 	{
// 		log_debug("find no srv type %d", stype);
// 	}

	return 0;
}

int CGameServer::sendToPlayer(SocketHandler* pHandler, NETInputPacket* pack)
{
	unsigned int uid = pack->GetDstSvid();
	if (uid > 0)
	{
		map<unsigned int, stPlayerHandler>::iterator itr = m_loginPlayer.find(uid);
		if (m_loginPlayer.end() != itr && itr->second.m_phandler)
		{
			itr->second.m_phandler->Send(pack);
		}
		else
		{
// 			for (map<unsigned int, CClientHandler*>::iterator itor1 = m_loginPlayer.begin(); itor1 != m_loginPlayer.end(); ++itor1)
// 			{
// 				log_debug("uid,%d,flowid,%d,\r\n", itor1->first, itor1->second->m_HandlerID);
// 			}
			log_error("pack from srv find no player,%d,cmd,%d,from,%d", uid, pack->GetCmdType(), pHandler->getType());
		}
	}
	else
	{
		log_error("pack from srv no uid,%d,cmd,%d,from,%d", uid, pack->GetCmdType(), pHandler->getType());
	}

}

int CGameServer::ProcEventBackConn(int ev_id, SpiderEvent* pEvent)
{
// 	if(pEvent && pEvent->evParam.ptr)
// 	{
// 		CClient* client = (CClient*)pEvent->evParam.ptr;
// 		unsigned short stype =  client->getType();
// 		unsigned int sid = client->getId();
// 		map<unsigned short, map<unsigned int, CClient*> >::iterator itor = m_node.find(stype);
// 		if (m_node.end() != itor)
// 		{
// 			itor->second[sid] = client;
// 		}
// 		else
// 		{
// 			m_node.insert(make_pair(stype, map<unsigned int, CClient*>()));
// 			m_node[stype].insert(make_pair(sid, client));
// 		}
// 		
// 		map<unsigned short, vector<unsigned int> >::iterator vitor = m_nodeId.find(stype);
// 		if(m_nodeId.end() != vitor)
// 		{
// 			vector<unsigned int>::iterator vitor1 = ::find(vitor->second.begin(), vitor->second.end(), sid);
// 			if (vitor->second.end() == vitor1)
// 			{
// 				vitor->second.push_back(sid);
// 				::sort(vitor->second.begin(), vitor->second.end());
// 			}
// 			
// 		}
// 		else
// 		{
// 			m_nodeId.insert(make_pair(stype, vector<unsigned int>()));
// 			m_nodeId[stype].push_back(sid);
// 		}
// 	}
	if (pEvent && pEvent->evParam.ptr)
	{
		CClient* client = (CClient*)pEvent->evParam.ptr;

		if (SERVER_TYPE_ONLINE == client->getType())
		{
			synOnline(client);
		}
	}
	return 0;
}

int CGameServer::ProcEventBackClose(int ev_id, SpiderEvent* pEvent)
{
	if (!(pEvent && pEvent->evParam.ptr))
		return -1;

 	CClient* client = (CClient*)pEvent->evParam.ptr;
	unsigned short stype = client->getType();
	if (SERVER_TYPE_ROOMALLOC == stype)
	{
		unsigned int sid = client->getId();

		map<unsigned int, unsigned int>::const_iterator itor = m_sidGameid.find(sid);
		if (m_sidGameid.end() != itor)
		{
			map<unsigned int, set<unsigned int> >::iterator itor1 = m_roomAlloc.find(itor->second);
			if (m_roomAlloc.end() != itor1)
			{
				itor1->second.erase(sid);
				log_info("room alloc svid,%u,gameid,%u,close",sid, itor->second);
			}

			m_sidGameid.erase(itor);
		}
	}
 	
	return 0;
}

int CGameServer::ProcEventClientClose(int ev_id, SpiderEvent* pEvent)
{
	log_debug("client close event");
	if (pEvent && pEvent->evParam.ptr)
	{
		CClientHandler* handler = (CClientHandler*)pEvent->evParam.ptr;
		unsigned int uid = handler->getId();
		log_debug("client close event,uid,%d,flowid,%d",uid, handler->m_HandlerID);
		if (uid > 0)
		{
			map<unsigned int, stPlayerHandler>::iterator itor = m_loginPlayer.find(uid);
			if (m_loginPlayer.end() != itor)
			{
				m_loginPlayer.erase(itor);

				synToOnlineOff(uid);
				log_debug("player close,uid,%d", uid);
			}
		}

		unsigned int flowid = handler->m_HandlerID;
		map<unsigned int, stPlayerHandler>::iterator itor = m_unloginPlayer.find(flowid);
		if (m_unloginPlayer.end() != itor)
		{
			m_unloginPlayer.erase(itor);
			log_debug("player no login close,uid,%d, flowid,%d", flowid, handler->m_HandlerID);
		}

		map<unsigned int, stPlayerHandler>::iterator itor1 = m_kickedPlayer.find(flowid);
		if (m_kickedPlayer.end() != itor1)
		{
			m_kickedPlayer.erase(itor1);
			log_debug("kicked player close,uid,%d, flowid,%d", flowid, handler->m_HandlerID);
		}

// 			for (map<unsigned int, stPlayerHandler>::iterator itor = m_unloginPlayer.begin(); m_unloginPlayer.end() != itor; ++itor)
// 			{
// 				if (itor->second.m_phandler && handler->m_HandlerID == itor->second.m_phandler->m_HandlerID)
// 				{
// 					m_unloginPlayer.erase(itor);
// 					log_debug("player no login close,uid,%d, flowid,%d", uid, handler->m_HandlerID);
// 					break;
// 				}
// 			}
	}

	return 0;
}

int CGameServer::ProcEventGameInit(int ev_id, SpiderEvent* pEvent)
{
	if (m_timerflag)
		return 0;

	StartTimer(TIMERID_HEART_BEAT_SYN, g_heartbeat_syn_dur, true);
	m_timerflag = true;

	return 0;
}

int CGameServer::ProcEventPublishService(int ev_id, SpiderEvent* pEvent)
{
	if (!(pEvent && pEvent->evParam.ptr))
		return -1;

	ServiceConf* pserviceConf = (ServiceConf*)pEvent->evParam.ptr;
	if (SERVER_TYPE_ONLINE == pserviceConf->server_type)
	{
		while (!m_synOnlineSid.empty())
		{
			unsigned int sid = m_synOnlineSid.front();
			procSynOnline(sid);
			m_synOnlineSid.pop();
			log_debug("service pubulis ready,proc srv id,%d", sid);
		}
	}
	return 0;
}

int CGameServer::ProcConnCheck(int ev_id, SpiderEvent* pEvent)
{
	if (!(pEvent && pEvent->evParam.ptr))
		return -1;

	ServerData* pconnItem = (ServerData*)pEvent->evParam.ptr;
	if (SERVER_TYPE_ROOMALLOC == pconnItem->type)
	{
		if (pconnItem->param1 <= 0)
		{
			log_error("wrong gameid param,%d", pconnItem->param1);
				return -1;
		}
		if (pconnItem->svid <= 0)
		{
			log_error("wrong svid param,%d", pconnItem->svid);
				return -1;
		}
		unsigned int sid = pconnItem->svid;
		unsigned int gameid = pconnItem->param1;

		map<unsigned int, unsigned int>::const_iterator itor = m_sidGameid.find(sid);
		if (m_sidGameid.end() != itor)
		{
			map<unsigned int, set<unsigned int> >::iterator itor1 = m_roomAlloc.find(itor->second);
			if (m_roomAlloc.end() != itor1)
			{
				itor1->second.erase(sid);
			}

			m_sidGameid.erase(itor);
		}

		m_roomAlloc[gameid].insert(sid);
		m_sidGameid.insert(std::make_pair(sid, gameid));
		log_debug("room alloc reg,svid,%u,gameid,%u", sid, gameid);
	}

	return 0;
}
void CGameServer::ProcHeartBeat(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	pHandler->Send(inputPkg);
}

int CGameServer::synToOnlineOn(unsigned int uid)
{
	NETOutputPacket pack;
	pack.Begin(ONLINE_ONLINE);
	pack.WriteInt(uid);
	pack.WriteInt(TGlobal::_svid);
	pack.End();

	srvtypeModSend(SERVER_TYPE_ONLINE, uid, &pack);
	return 0;
}

int CGameServer::synToOnlineOff(unsigned int uid)
{
	NETOutputPacket pack;
	pack.Begin(ONLINE_OFFLINE);
	pack.WriteInt(uid);
	pack.End();

	srvtypeModSend(SERVER_TYPE_ONLINE, uid, &pack);
	return 0;
}

int CGameServer::synOnline(CClient* client)
{

	if (!(m_pHost && m_pHost->m_pNode))
		return -1;

	unsigned int sid = client->getId();
	ServiceTypeList::const_iterator itor =  m_pHost->m_pNode->m_serviceTypeList.find(SERVER_TYPE_ONLINE);
	if (m_pHost->m_pNode->m_serviceTypeList.end() != itor && itor->second.size() > 0)
	{
		procSynOnline(sid, client);
	}
	else
	{
		m_synOnlineSid.push(sid);
		log_debug("service pulish not ready,online srv id,%d", sid);
	}



	return 0;
}

void CGameServer::procSynOnline(const unsigned int sid, CClient* client)
{
	ServiceTypeList::const_iterator itor = m_pHost->m_pNode->m_serviceTypeList.find(SERVER_TYPE_ONLINE);
	if (m_pHost->m_pNode->m_serviceTypeList.end() != itor && itor->second.size() > 0)
	{
		int index = 0;
		for (ServiceVect::const_iterator itor1 = itor->second.begin(); itor->second.end() != itor1; ++itor1, ++index)
		{
			if (sid == itor1->svid)
			{
				break;
			}
		}
		if (index < itor->second.size())
		{
			online::OnlineSynReq req;
			req.set_agentid(TGlobal::_svid);
			for (map<unsigned int, stPlayerHandler>::iterator itor2 = m_loginPlayer.begin(); m_loginPlayer.end() != itor2; ++itor2)
			{
				if (index == itor2->first % itor->second.size())
				{
					req.add_uids(itor2->first);
				}

			}
			if (client)
			{
				m_pHost->SendPb(client, online::ONLINE_CMD_ONLINE_SYN, SERVER_TYPE_ONLINE, client->getId(), &req);
			}
			else if (sid > 0)
			{
				m_pHost->SendtoOneSrv(online::ONLINE_CMD_ONLINE_SYN, &req, SERVER_TYPE_ONLINE, sid);
			}
			
			log_debug("online srv id,%d,index,%d,service num,%d", sid, index, itor->second.size());
		}
		else
		{
			log_error("service find no srv id,online srv id,%d", sid);
		}
		log_debug("service pulish ready,online srv id,%d", sid);
	}
	else
	{
		log_error("service pulish not ready,online srv id,%d", sid);
	}

	return;
}

int CGameServer::procHeartBeatSyn(void)
{
	for (map<unsigned int, stPlayerHandler>::iterator itor = m_loginPlayer.begin(); m_loginPlayer.end() != itor; )
	{
		if (itor->second.m_phandler)
		{
			if (itor->second.m_phandler->addTick() >= 3)
			{
				log_debug("login player destory,uid,%d,id,%d,flowid,%d", itor->first, itor->second.m_phandler->getId(), itor->second.m_phandler->m_HandlerID);
				if (itor->second.m_phandler->m_HandlerID > 0)
				{
					m_unloginPlayer.erase(itor->second.m_phandler->m_HandlerID);
					m_kickedPlayer.erase(itor->second.m_phandler->m_HandlerID);
				}
				synToOnlineOff(itor->first);
				itor->second.m_phandler->Destroy();
				m_loginPlayer.erase(itor++);
				continue;
			}
			
			//itor->second.addcount();
		}
		++itor;
	}

	for (map<unsigned int, stPlayerHandler>::iterator itor = m_unloginPlayer.begin(); m_unloginPlayer.end() != itor; )
	{
		if (itor->second.m_phandler)
		{
			if (itor->second.m_phandler->addTick() >= 3)
			{
				log_debug("unlogin player destory,flow,%d,id,%d,flowid,%d", itor->first, itor->second.m_phandler->getId(), itor->second.m_phandler->m_HandlerID);
				if (itor->second.m_phandler->getId() > 0)
				{
					m_loginPlayer.erase(itor->second.m_phandler->getId());
				}
				m_kickedPlayer.erase(itor->second.m_phandler->m_HandlerID);

				itor->second.m_phandler->Destroy();
				m_unloginPlayer.erase(itor++);
				continue;
			}

			//itor->second.addcount();
		}
		++itor;
	}

	for (map<unsigned int, stPlayerHandler>::iterator itor = m_kickedPlayer.begin(); m_kickedPlayer.end() != itor; )
	{
		if (itor->second.m_phandler)
		{
			if (itor->second.m_phandler->addTick() >= 3)
			{
				log_debug("kicked player heart beat off,%d,id,%d,flowid,%d", itor->first, itor->second.m_phandler->getId(), itor->second.m_phandler->m_HandlerID);
				if (itor->second.m_phandler->getId() > 0)
				{
					m_loginPlayer.erase(itor->second.m_phandler->getId());
				}
				m_unloginPlayer.erase(itor->second.m_phandler->m_HandlerID);

				itor->second.m_phandler->Destroy();
				m_kickedPlayer.erase(itor++);
				continue;
			}

			//itor->second.addcount();
		}
		++itor;
	}

	log_info("online,svid,%u,sum,%u,n1,%u,n2,%u", TGlobal::_svid, m_loginPlayer.size(), m_unloginPlayer.size(), m_kickedPlayer.size());
	return 0;
}

void CGameServer::resetSynCount(SocketHandler* pHandler)
{
	//CClientHandler* handler = dynamic_cast<CClientHandler*>(pHandler);
	if (pHandler)
	{
		pHandler->resetTick();
// 		unsigned int uid = handler->getId();
// 		if (uid > 0)
// 		{
// 			map<unsigned int, stPlayerHandler>::iterator itor = m_loginPlayer.find(uid);
// 			if (m_loginPlayer.end() != itor)
// 				itor->second.resetcount();
// 
// 			log_debug("reset syn count,%d",uid);
// 		}
// 		else
// 		{
// 			map<unsigned int, stPlayerHandler>::iterator itor = m_unloginPlayer.find(handler->m_HandlerID);
// 			if (m_unloginPlayer.end() != itor)
// 				itor->second.resetcount();
// 
// 			log_debug("reset syn count,flowid,%d", handler->m_HandlerID);
// 
// 			//do not reset kicked player, let kicked player heart beat off
// 		}
	}
	else
	{
		log_error("dynamic_cast err");
	}
}

void CGameServer::kick(const unsigned int uid, const int reason, const bool syn)
{
	map<unsigned int, stPlayerHandler>::iterator itor = m_loginPlayer.find(uid);
	if (m_loginPlayer.end() != itor && itor->second.m_phandler)
	{
		log_debug("kick, uid,%d, flowid,%d", uid, itor->second.m_phandler->m_HandlerID);

		agent::KickPush kicknotify;
		kicknotify.set_uid(uid);
		kicknotify.set_result(reason);
		m_pHost->SendPlayerPb(itor->second.m_phandler, agent::AGENT_CMD_KICK, uid, &kicknotify);

		if (syn)
			synToOnlineOff(uid);

		//itor->second.m_phandler->Destroy();
		unsigned int flowid = itor->second.m_phandler->m_HandlerID;
		itor->second.m_phandler->setId(0);//clear palyer uid
		m_kickedPlayer.insert(std::make_pair(flowid, itor->second));
		m_loginPlayer.erase(itor);
	}
	return;
}
